/* 
This enhencement to Date object will return the date in your choosen format. Format parameters follows Python guidelines.

%a 	Locale’s abbreviated weekday name. 	 
%A 	Locale’s full weekday name. 	 
%b 	Locale’s abbreviated month name. 	 
%B 	Locale’s full month name. 	 
%d 	Day of the month as a decimal number [01,31]. 	 
%H 	Hour (24-hour clock) as a decimal number [00,23]. 	 
%I 	Hour (12-hour clock) as a decimal number [01,12]. 	 
%m 	Month as a decimal number [01,12]. 	 
%M 	Minute as a decimal number [00,59]. 	 
%S 	Second as a decimal number [00,61]. 	(3)
%y 	Year without century as a decimal number [00,99]. 	 
%Y 	Year with century as a decimal number. 	 
*/

Date.prototype.language = 'it';
Date.prototype.double_digit = true;
Date.prototype.week_days = { 
				'it' : [ 'domenica', 'luned&igrave;', 'marted&igrave;', 'mercoled&igrave;', 'gioved&igrave;', 'venerd&igrave;', 'sabato' ],
			     	'en' : [ 'Sunday', 'Monday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ] 
				};
Date.prototype.year_months = { 
				'it' : [ 'gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre' ],
				'en' : [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'Agoust', 'September', 'October', 'November', 'December' ] 
				};

Date.formatted = function ( format, date_input )
{
	if ( ! date_input ) 
		date_input = new Date ();
	else if ( typeof ( date_input ) === 'string' ) 
		date_input = Date.fromString ( date_input );
		//date_input = new Date ( Date.parse ( ( date_input ) ) );

	if ( typeof ( date_input ) !== 'object' ) return '';

	return date_input.format_date ( format );
};

Date.fromString = function ( str )
{
	if ( typeof ( str ) != 'string' ) return str;
	var d, h, t = str.split ( ' ' );
	d = t [ 0 ].match ( /([0-9]{4}).([0-9]{1,2}).([0-9]{1,2})/ );
	if ( t [ 1 ] ) h = t [ 1 ].match ( /([0-9]{1,2}).([0-9]{1,2}).([0-9]{1,2})/ );
	
	if ( ! d ) 
	{
		console.error ( "Invalid date: %s", str );
		return ;//new Date ();
	} else {
		if ( h ) return new Date ( d [ 1 ], parseInt ( d [ 2 ], 10 ) -1, parseInt ( d [ 3 ], 10 ), parseInt ( h [ 1 ], 10 ), parseInt ( h [ 2 ], 10 ), parseInt ( h [ 3 ], 10 ) );
	}
	return new Date ( d [ 1 ], parseInt ( d [ 2 ], 10 ) -1, parseInt ( d [ 3 ], 10 ) );
};

Date.prototype.format_date = function ( format )
{
	// find type of separator
	var dict = {
			'a' : '_get_day',
			'b' : '_get_month_name',
			'd' : '_get_date',
			'm' : '_get_month',
			'M' : '_get_minutes',
			'h' : '_time',
			'i' : '_time',
			'y' : '_get_year',
			's' : '_get_seconds'
			};
	var c, tmp, i, cback, is_fmt = false;
	var output = new String.buffer ();
	for ( c = 0; c < format.length ; c++ )
	{
		tmp = format [ c ];
		if ( tmp == '%' )
		{
			is_fmt = true;
			continue;
		}
		if ( is_fmt )
		{
			is_fmt = false;
			if ( dict.get ( tmp.toUpperCase () ) && dict.get ( tmp.toLowerCase() ) )
			{
				// if is defined in both , upper and lower case, than pick user choice
				cback = dict.get ( tmp );
			} else {
				// else we pass it as parameter
				cback = dict.get ( tmp.toLowerCase(), null );
			}
			if ( cback ) tmp = this [ cback ] ( tmp );
		}
		if ( tmp ) output.add ( tmp.toString () );
	}
	return output.toString ();
};

Date.prototype._get_day = function ( opt )
{
	var days = this.week_days [ this.language ];
	var js = this.getDay ();
	var out = days.get ( js, '' );
	if ( opt === 'a' ) out = out.substr ( 0, 3 );
	return out;
};

Date.prototype._get_month_name = function ( opt )
{
	var months = this.year_months [ this.language ];
	var js = this.getMonth ();
	var out = months.get ( js, '' );
	if ( opt === 'b' ) out = out.substr ( 0, 3 );
        return out; 
};

Date.prototype._time = function ( opt )
{
	var h = this.getHours ();
	if ( opt === 'i' && h > 12 ) h -= 12;
	return this.__double_digit ( h );
};

Date.prototype._get_year = function ( opt )
{
	var out = this.getFullYear ().toString ();
	if ( opt === 'y' ) out = out.substr ( 2 );
        return out; 
};

Date.prototype._get_date = function ()
{
	var date = this.getDate ();
	return this.__double_digit ( date );
};

Date.prototype._get_month = function ()
{
	var month = this.getMonth () + 1;
	return this.__double_digit ( month );
};

Date.prototype._get_minutes = function ()
{
	var mins = this.getMinutes ();
	return this.__double_digit ( mins );
};

Date.prototype._get_seconds = function ()
{
	var secs = this.getSeconds ();
	return this.__double_digit ( secs );
};

Date.prototype.__double_digit = function ( val )
{
	val = parseInt ( val, 10 );	
	if ( this.double_digit && val < 10 ) val = '0' + val.toString ();
	return val;
};

Date.prototype.set_language = function ( lang )
{
	this.language = lang;
};

Date.prototype.add_language = function ( lang, days, months )
{
	this.week_days [ lang ] = days;
	this.year_months [ lang ] = months;
};

Date.diff_days = function ( d1, d2 )
{
	d1 = Date.fromString ( d1 );
	d2 = Date.fromString ( d2 );

	return ( d2 - d1 ) / 86400000;
};

( function () {
	var D = new Date ( '2011-06-02T09:34:29+02:00' ) ;
	if ( !D || D !== 1307000069000 )
	{
		Date.fromISO = function ( s )
		{
			var day, tz,
			rx = /^(\d{4}\-\d\d\-\d\d([tT][\d:\.]*)?)([zZ]|([s\-])(\d\d):(\d\d))?$/,
			p = rx.exec ( s ) || [];
			if ( p [ 1 ] )
			{
				day = p [ 1 ] .split ( /\D/ ) ;
				for ( var i = 0, L = day.length; i < L; i ++ )
				{
					day [ i ] = parseInt ( day [ i ] , 10 ) || 0;
				}
				day [ 1 ] -= 1;
				day = new Date ( Date.UTC.apply ( Date, day ) ) ;
				if ( ! day.getDate () ) return NaN;
				if ( p [ 5 ] )
				{
					tz = ( parseInt ( p [ 5 ] , 10 ) *60 ) ;
					if ( p [ 6 ] ) tz += parseInt ( p [ 6 ] , 10 ) ;
					if ( p [ 4 ] == '+' ) tz *= -1;
					if ( tz ) day.setUTCMinutes ( day.getUTCMinutes () + tz ) ;
				}
				return day;
			}
			return NaN;
		}
	} else {
		Date.fromISO = function ( s ) {
			return new Date ( s );
		}
	}
} ) ();
